home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / v10n12.arc / WINEXT.C < prev    next >
Text File  |  1991-05-30  |  19KB  |  593 lines

  1.  
  2. //  WinExt 1.0    by Fran Finnegan (76244,145)
  3. //  Copyright (c) 1991 Finnegan O'Malley & Company Inc.  All Rights Reserved.
  4. //  First Published in PC Magazine, June 25, 1991
  5.  
  6. //  developed using Microsoft C 5.10 (Medium memory model only)
  7.  
  8. #include <direct.h>
  9. #include <dos.h>
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13.  
  14. #define NOCOMM    //  dumb
  15. #include <windows.h>
  16.  
  17. #include "winext.h"
  18. #include "dlg.h"
  19.  
  20. //////////////////////////////////////////////////////////////////////
  21.  
  22. #define WINEXT_OPTIONS    1
  23. #define WINEXT_DIR    1
  24. #define WINEXT_APP    2
  25.  
  26. #define SHOW_MINIMIZED    SW_SHOWMINNOACTIVE
  27. #define SHOW_MAXIMIZED    SW_SHOWMAXIMIZED
  28.  
  29. #define NO        0
  30. #define YES        1
  31.  
  32. #define argc        __argc
  33. #define argv        __argv
  34.  
  35. extern    int        argc;
  36. extern    char        **argv;
  37.  
  38. typedef struct
  39.     {
  40.     int        iCmdShow;
  41.     LPSTR        lpsCmdLine;
  42.     HANDLE        hPrevInst;
  43.     HANDLE        hInst;
  44.     // stack frame prior to WinMain
  45.     }        NEAR *NPWINMAIN;
  46.  
  47. extern    int    PASCAL    WinMain
  48.     (
  49.     HANDLE        ahInst,
  50.     HANDLE        ahPrevInst,
  51.     LPSTR        alpsCmdLine,
  52.     int        aiCmdShow
  53.     );
  54.  
  55. extern    int FAR PASCAL    DlgProc
  56.     (
  57.     HWND        ahDlg,
  58.     WORD        awMsg,
  59.     WORD        awParam,
  60.     DWORD        alParam
  61.     );
  62.  
  63. #pragma alloc_text(       _TEXT, WinMain            )
  64. #pragma alloc_text( DLGPROC_TEXT, DlgProc            )
  65.  
  66. #define Local(w)    LocalLock(LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, w))
  67.  
  68. #define sizeof_mpsBuffer    (512        )
  69. #define sizeof_mpsCmdLine    (_MAX_PATH * 2    )
  70. #define sizeof_mpsWinIniExt    (256        )
  71. #define sizeof_mpsFileName    (_MAX_PATH    )
  72. #define sizeof_mpOf        sizeof(OFSTRUCT)
  73.  
  74. static    NPWINMAIN    mnpWinMain;
  75. static    HWND        mhDlg;    //  required for Usage recursion
  76. static    POFSTRUCT    mpOf;    //  contains the d:\path\FILENAME.EXT
  77. static    BOOL        sbUsage;
  78. static    char        *mpsBuffer    ,
  79.             *mpsCmdLine    ,    //  the New Command Line
  80.             *mpsWinIniExt    ,    //  ext=string
  81.             *mpsFileName    ;    //  d:\path\FILENAME
  82.  
  83. /******************************************************************************
  84. Usage:    WIN.INI [Extensions]:    ext=winext [?-+] dir app [args] ^.ext [args]
  85.     Program Manager item:    winext.exe [?-+] dir app [args] file
  86.  
  87. where:    ext    Extension of associated data file (EXT part of FILENAME.EXT)
  88.     winext    WinExt (WINEXT.EXE should be somewhere on the environment PATH)
  89.     ?-+    Optional WinExt arguments:  ?=dialog; -=minimize; +=maximize
  90.     dir    Current Working Directory:  start-up directory (path, . or ..)
  91.     app    Program to run:  .EXE, .COM, .BAT or .PIF file specification
  92.     args    Optional app arguments (for embedded blanks, use double-quotes)
  93.     ^.ext    File placeholder:  may be ^, ^. or * (ignore .ext, ext or file)
  94.     args    More optional app arguments (WIN.INI [Extensions] entry only)
  95.     file    Qualified file specification:  may be .\file or * (ignore file)
  96.  
  97. winext, dir, app, ^.ext and file are required; ?-+ and args are optional ([]s).
  98. dir may be subsequently overridden by a Start-up Directory in an app .PIF file.
  99. path\FILENAME substitutions are made for multiple occurrences of the caret (^).
  100. Environment-variable substitutions are made just as in .BAT files:  %variable%.
  101. ******************************************************************************/
  102.  
  103. extern    int    PASCAL    WinMain
  104.     (
  105.     HANDLE        ahInst,
  106.     HANDLE        ahPrevInst,
  107.     LPSTR        alpsCmdLine,
  108.     int        aiCmdShow
  109.     )
  110. {
  111. auto    char        *apsFirst,
  112.             *apsLast,
  113.             *apsEnv;
  114. auto    FARPROC     aFpDlgProc;
  115. auto    WORD        awCode;
  116. auto    int        aiDialogBox    = NO,
  117.             aiFileAsterisk    = NO;
  118. auto    MSG        aMsg;
  119.  
  120. static    char        sszError[] = "Error.",
  121.             sszBlank[] = " ",
  122.             sszQuote[] = "\"";
  123.  
  124. if (NULL == mnpWinMain)     //  ignore recursion from dialog proc
  125.     {
  126.     //    possibly become a "TSR" on a Load with no arguments
  127.     if (0 == ahPrevInst     //  look for a previous "TSR" instance
  128.     &&    1 == argc)        //  only do this on the first instance
  129.     switch (aiCmdShow)
  130.         {
  131.         case SW_HIDE       :
  132.         case SW_SHOWMINIMIZED  :
  133.         case SW_MINIMIZE       :
  134.         case SW_SHOWMINNOACTIVE:
  135.         while (YES)    //  go into an infinite loop
  136.             PeekMessage(&aMsg, 0, WM_NULL, WM_NULL, PM_REMOVE);
  137.         //  nothing below this line will be executed
  138.         }
  139.  
  140.     //    remember the first set of WinMain arguments for dialog proc
  141.     mnpWinMain = (NPWINMAIN)&aiCmdShow;
  142.  
  143.     //    allocate all local storage from largest to smallest
  144.     mpsBuffer        = Local(sizeof_mpsBuffer   );
  145.     mpsCmdLine        = Local(sizeof_mpsCmdLine  );
  146.     mpsWinIniExt    = Local(sizeof_mpsWinIniExt);
  147.     mpsFileName     = Local(sizeof_mpsFileName );
  148.     mpOf     = (POFSTRUCT)Local(sizeof_mpOf       );
  149.  
  150.     //    verify that allocations succeeded
  151.     if (mpsBuffer
  152.     &&    mpsCmdLine
  153.     &&    mpsWinIniExt
  154.     &&    mpsFileName
  155.     &&    mpOf        )
  156.     lstrcpy(mpsCmdLine, alpsCmdLine);    //  to check for '^'
  157.     else    //  a LocalAlloc failed
  158.     {
  159.     MessageBox(0, sszError, "WinExt", MB_ICONSTOP | MB_OK);
  160.     return 0;
  161.     }
  162.     }
  163.  
  164. //  look for the WinExt options:  ?=dialog; -=minimize; +=maximize
  165. if (2 <= argc)
  166.     switch (*argv[WINEXT_OPTIONS])
  167.     {
  168.     case '?':
  169.     case '-':
  170.     case '+':
  171.         while (*argv[WINEXT_OPTIONS])
  172.         switch (*(argv[WINEXT_OPTIONS]++))
  173.             {
  174.             default :    //  bad option, so show dialog box
  175.             case '?':   aiDialogBox = YES;              break;
  176.             case '-':   aiCmdShow = SHOW_MINIMIZED;     break;
  177.             case '+':   //  if minimize, don't maximize
  178.             switch (aiCmdShow)
  179.                 {
  180.                 default:
  181.                 aiCmdShow = SHOW_MAXIMIZED;    break;
  182.                 case SW_HIDE       :
  183.                 case SW_SHOWMINIMIZED  :
  184.                 case SW_MINIMIZE       :
  185.                 case SW_SHOWMINNOACTIVE:        break;
  186.                 }
  187.             break;
  188.             }
  189.         argc--;  argv++;    //  hide WinExt options
  190.         break;
  191.     }
  192.  
  193. //  there must be at least three arguments:  winext dir app ^.ext
  194. if (4 <= argc--
  195. &&  NULL == strchr(mpsCmdLine, '^'))    //  '^' not allowed on Command Line
  196.     {
  197.     //    argv[argc] is probably the ^.ext (FILENAME.EXT), because
  198.     //        everything after the '^' is ignored by most shells
  199.  
  200.     //    check for '*', which means no FILENAME.EXT is to be used
  201.     if ('*' == argv[argc][0])
  202.     aiFileAsterisk = YES;    //  turn file-asterisk flag on
  203.     else
  204.     {
  205.     //  use the partially- or fully-qualified d:\path\FILENAME.EXT
  206.     lstrcpy(mpOf->szPathName, argv[argc]);
  207.     if (mpOf->szPathName[0] != '\\'  //   \filespec
  208.     &&  mpOf->szPathName[0] != '.'   //  .\filespec or ..\filespec
  209.     &&  mpOf->szPathName[1] != ':')  //  d:filespec or d:\filespec
  210.         OpenFile(argv[argc], mpOf, OF_PARSE);  //  fully-qualified
  211.  
  212.     //  get the d:\path\FILENAME (no .EXT) for '^' substitution
  213.     lstrcpy(mpsFileName, mpOf->szPathName);
  214.     if (apsLast = strrchr(mpsFileName, '.'))  //  if there's a '.'
  215.         {
  216.         *apsLast = '\0';                    //  remove the .EXT
  217.         lstrcpy(mpsWinIniExt, ++apsLast);    //  get the EXT
  218.         lstrcat(mpsWinIniExt, "=");         //  add the '='
  219.  
  220.         //    use EXT to get the WIN.INI [Extensions] ext= string
  221.         GetProfileString("Extensions", apsLast, "",
  222.                mpsWinIniExt + lstrlen(mpsWinIniExt),
  223.             sizeof_mpsWinIniExt - (3 + 1));
  224.         }
  225.     }
  226.  
  227.     //    change the Current Working Directory to dir
  228.     if (('.' == argv[WINEXT_DIR][0]     //  check for '.' only
  229.     &&    '\0' == argv[WINEXT_DIR][1])
  230.     ||    (':' == argv[WINEXT_DIR][1]     //  check for "d:" only
  231.     &&    '\0' == argv[WINEXT_DIR][2])
  232.     ||    0 == chdir(argv[WINEXT_DIR]))    //  change directory
  233.     {
  234.     //  if dir is valid, change drive to any d: in dir
  235.     if (':' == argv[WINEXT_DIR][1])         //  look for "d:"
  236.         _dos_setdrive(argv[WINEXT_DIR][0] & 0x1F, &awCode);
  237.  
  238.     //  create the New Command Line, beginning with app
  239.     lstrcpy(mpsCmdLine, argv[WINEXT_APP]);
  240.  
  241.     //  append any/all args on the left of the FILENAME.EXT
  242.     for (argc -= 3, argv += 3;  argc;  argc--, argv++)
  243.         {
  244.         lstrcat(mpsCmdLine, sszBlank);    //  append ' '
  245.         if (apsFirst = strchr(*argv, ' '))  //  embedded ' '?
  246.         lstrcat(mpsCmdLine, sszQuote);    //    prepend '"'
  247.         lstrcat(mpsCmdLine, *argv);     //  then argument
  248.         if (apsFirst)            //  embedded ' '?
  249.         lstrcat(mpsCmdLine, sszQuote);    //    append '"'
  250.         }
  251.  
  252.     //  add the d:\path\FILENAME.EXT
  253.     if (NO == aiFileAsterisk)        //  if no '*'
  254.         {
  255.         lstrcat(mpsCmdLine, sszBlank);    //  append ' ' and
  256.         lstrcat(mpsCmdLine, mpOf->szPathName);  //    the filespec
  257.         }
  258.  
  259.     //  look in ext= string for '^' and args on right
  260.     if (apsFirst = strchr(mpsWinIniExt, '^'))
  261.         {
  262.         //    assuming the first '^' in ext=, remove the old .EXT
  263.         *strrchr(mpsCmdLine, '.') = '\0';
  264.  
  265.         //    append ext= string .ext and any args on the right
  266.         lstrcat(mpsCmdLine, apsFirst + 1);
  267.         }
  268.  
  269.     //  do any other substitutions for '^' of d:\path\FILENAME
  270.     while (apsFirst = strchr(mpsCmdLine, '^'))  //  if there's '^'
  271.         {
  272.         lstrcpy(mpsBuffer, mpsFileName);    // d:\path\FILENAME
  273.         lstrcat(mpsBuffer, apsFirst + 1);    // post-'^' stuff
  274.         lstrcpy(apsFirst, mpsBuffer);    // New Command Line
  275.         }
  276.  
  277.     //  do any environment %variable% string substitutions
  278.     while ((apsFirst = strchr(mpsCmdLine  , '%'))
  279.     &&     (apsLast  = strchr(apsFirst + 1, '%')))
  280.         {
  281.         *apsLast = mpsBuffer[0] = '\0';     // remove last '%'
  282.         if ((apsEnv = getenv(    apsFirst + 1 ))   // UC/lc
  283.         ||    (apsEnv = getenv(strupr(apsFirst + 1))))  // UC
  284.         lstrcpy(mpsBuffer, apsEnv);    // env variable
  285.         lstrcat(mpsBuffer, apsLast + 1);    // post-'%' stuff
  286.         lstrcpy(apsFirst, mpsBuffer);    // New Command Line
  287.         }
  288.  
  289.     //  show the dialog box if it was requested or
  290.     //            if the New Command Line is too long
  291.     apsFirst = strchr(mpsCmdLine, ' ');     //  first blank after app
  292.     if (NULL == apsFirst)            //  no blank after app
  293.         apsFirst = mpsCmdLine + lstrlen(mpsCmdLine);
  294.     if (aiDialogBox
  295.     || (apsFirst - mpsCmdLine + 128) < lstrlen(mpsCmdLine))   //  too long?
  296.         {
  297.         aiDialogBox = DialogBox(ahInst, MAKEINTRESOURCE(DLG), 0,
  298.                 aFpDlgProc = MakeProcInstance(DlgProc, ahInst));
  299.         FreeProcInstance(aFpDlgProc);
  300.         if (ID_PB_CANCEL == aiDialogBox)
  301.         return 0;   //    premature termination on Cancel
  302.         }
  303.  
  304.     //  execute the New Command Line
  305.     if (32 < (awCode = WinExec(mpsCmdLine, aiCmdShow)))
  306.         return 0;    //  normal termination
  307.  
  308.     //  if above Exec fails, fall through and report error code
  309.     }
  310.     else    //    requested dir is invalid
  311.     {
  312.     awCode = 3;    //  error code for "path not valid" string
  313.     lstrcpy(mpsCmdLine, argv[WINEXT_DIR]);    //  caption is dir
  314.     }
  315.  
  316.     //    load error text from .RC STRINGTABLE and show message box
  317.     if (0 == LoadString(ahInst, awCode, mpsBuffer, sizeof_mpsBuffer))
  318.     lstrcpy(mpsBuffer, sszError);    //  unknown-code string
  319.     MessageBox(0, mpsBuffer, mpsCmdLine, MB_ICONSTOP | MB_OK);
  320.     }
  321.  
  322. //  put up a "usage" dialog box if requested or if something's wrong
  323. sbUsage = YES;
  324. DialogBox(ahInst, MAKEINTRESOURCE(USAGE), mhDlg,
  325.     aFpDlgProc = MakeProcInstance(DlgProc, ahInst));
  326. FreeProcInstance(aFpDlgProc);
  327. sbUsage = NO;
  328. return 0;   //    error termination
  329. }
  330.  
  331. //////////////////////////////////////////////////////////////////////
  332.  
  333. extern    int FAR PASCAL    DlgProc
  334.     (
  335.     HWND        ahDlg,
  336.     WORD        awMsg,
  337.     WORD        awParam,
  338.     DWORD        alParam
  339.     )
  340. {
  341. auto    WORD        awCode,
  342.             awCmdLen;
  343. auto    RECT        aRt;
  344. auto    char        *apsCmdLine;
  345.  
  346. static    HWND        shCtlExecute,
  347.             shCtlCancel ,
  348.             shCtlReset  ,
  349.             shCtlUsage  ,
  350.             shCtlExt    ,
  351.             shCtlCWD    ,
  352.             shCtlPIF    ,
  353.             shCtlCmd    ,
  354.             shCtlDefID  ;
  355. static    WORD        swCmdLen;
  356. static    int        siID_RB_SW;
  357. static    char        sszPIF[] = ".PIF";
  358.  
  359. switch (awMsg)
  360.     {
  361.     case WM_INITDIALOG:
  362.     //  center dialog box
  363.     GetWindowRect(ahDlg, &aRt);
  364.     OffsetRect(&aRt, -aRt.left  , -aRt.top     );
  365.     MoveWindow(ahDlg,   //    this is the correct way to center a dialog:
  366.         ((GetSystemMetrics(SM_CXSCREEN) - aRt.right ) / 2 + 4) & ~7,
  367.          (GetSystemMetrics(SM_CYSCREEN) - aRt.bottom) / 2,
  368.         aRt.right , aRt.bottom, NO);
  369.  
  370.     //  set dialog caption to module name
  371.     GetModuleFileName(mnpWinMain->hInst, mpsBuffer, sizeof_mpsBuffer);
  372.     SetWindowText(ahDlg, mpsBuffer);
  373.  
  374.     //  if "usage" dialog box, done
  375.     if (sbUsage)
  376.         {
  377.         SetDlgItemText(ahDlg, ID_E_CMD, mnpWinMain->lpsCmdLine);
  378.         return YES;     //    did process the message
  379.         }
  380.  
  381.     //  save all relevant handles
  382.     shCtlDefID   =
  383.     shCtlExecute = GetDlgItem(ahDlg, ID_PB_EXECUTE);
  384.     shCtlCancel  = GetDlgItem(ahDlg, ID_PB_CANCEL );
  385.     shCtlReset   = GetDlgItem(ahDlg, ID_PB_RESET  );
  386.     shCtlUsage   = GetDlgItem(ahDlg, ID_PB_USAGE  );
  387.     shCtlExt     = GetDlgItem(ahDlg, ID_T_EXT     );
  388.     shCtlCWD     = GetDlgItem(ahDlg, ID_T_CWD     );
  389.     shCtlPIF     = GetDlgItem(ahDlg, ID_T_PIF     );
  390.     shCtlCmd     = GetDlgItem(ahDlg, ID_E_CMD     );
  391.  
  392.     //  set ext= text controls
  393.     if (mpsWinIniExt[0])    //  WIN.INI [Extensions]
  394.         SetWindowText(shCtlExt, mpsWinIniExt);
  395.     else            //  WinExt Command Line
  396.         {
  397.         GetWindowText(shCtlExt, mpsBuffer, sizeof_mpsBuffer);
  398.         SetWindowText(GetDlgItem(ahDlg, ID_GB_EXTBOX), mpsBuffer);
  399.         SetWindowText(shCtlExt, mnpWinMain->lpsCmdLine);
  400.         }
  401.  
  402.     //  set New Command Line edit control
  403.     apsCmdLine = strchr(mpsCmdLine, ' ');   //  first blank after app
  404.     if (NULL == apsCmdLine)         //  no blank after app
  405.         apsCmdLine = mpsCmdLine + lstrlen(mpsCmdLine);
  406.     swCmdLen = apsCmdLine - mpsCmdLine + 128;   //    maximum command length
  407.     if (swCmdLen < lstrlen(mpsCmdLine))    //  is New Command Line longer?
  408.         {
  409.         GetWindowText(shCtlCWD, mpsBuffer, sizeof_mpsBuffer);  //  caption
  410.         MessageBox(0, mpsCmdLine, mpsBuffer, MB_ICONEXCLAMATION | MB_OK);
  411.         mpsCmdLine[swCmdLen] = '\0';        //  arguments:  ' ' + 127 bytes
  412.         }
  413.     SendMessage(shCtlCmd, EM_LIMITTEXT, swCmdLen, 0L);
  414.     SetWindowText(shCtlCmd, mpsCmdLine);    //  New Command Line
  415.  
  416.     //  set cwd text control        //  caption of above MessageBox
  417.     getcwd(mpsBuffer, sizeof_mpsBuffer);    //  no trailing '\'
  418.     SetWindowText(shCtlCWD, mpsBuffer);    //  Current Working Directory
  419.  
  420.     //  search for a .PIF file
  421.     lstrcpy(mpsBuffer , mpsCmdLine);
  422.     if ( apsCmdLine = strchr(mpsBuffer, ' '))       //  use only app
  423.         *apsCmdLine = '\0';
  424.     if (':' == mpsBuffer[1])                        //  remove any d:
  425.         lstrcpy(mpsBuffer , mpsBuffer + 2);
  426.     if ( apsCmdLine = strrchr(mpsBuffer, '\\'))     //  remove any path
  427.         lstrcpy(mpsBuffer , apsCmdLine + 1);
  428.     if ( apsCmdLine = strchr(mpsBuffer, '.'))       //  rename to .PIF
  429.         lstrcpy(apsCmdLine, sszPIF);
  430.     else
  431.         lstrcat(mpsBuffer , sszPIF);
  432.     if (-1 < OpenFile(mpsBuffer , mpOf, OF_EXIST))    //  see if .PIF exists
  433.         SetWindowText(shCtlPIF, mpOf->szPathName);
  434.     else                        //  hide .PIF control
  435.         MoveWindow(shCtlPIF, 0, 0, 0, 0, NO);
  436.  
  437.     //  set the radio button based on iCmdShow
  438.     switch (mnpWinMain->iCmdShow)
  439.         {
  440.     //  case SW_SHOWNORMAL       :
  441.     //  case SW_SHOWNOACTIVATE :
  442.     //  case SW_SHOW       :
  443.     //  case SW_SHOWNA       :
  444.     //  case SW_RESTORE       :
  445.         default           :    siID_RB_SW = ID_RB_DEF;     break;
  446.  
  447.         case SW_HIDE       :
  448.         case SW_SHOWMINIMIZED  :
  449.         case SW_MINIMIZE       :
  450.         case SW_SHOWMINNOACTIVE:    siID_RB_SW = ID_RB_MIN;     break;
  451.  
  452.         case SW_SHOWMAXIMIZED  :    siID_RB_SW = ID_RB_MAX;     break;
  453.         }
  454.     CheckRadioButton(ahDlg, ID_RB_DEF, ID_RB_MAX, siID_RB_SW);
  455.  
  456.     return YES;    //  did process the message
  457.  
  458.     case WM_COMMAND:
  459.     awCode = HIWORD(alParam);
  460.     switch (awParam)
  461.         {
  462.         case ID_E_CMD:
  463.         //  enable/disable Execute based on the New Command Line
  464.         if (GetWindowTextLength(shCtlCmd))
  465.             {
  466.             shCtlDefID = shCtlExecute;
  467.             SendMessage(ahDlg, DM_SETDEFID, ID_PB_EXECUTE, 0L);
  468.             EnableWindow(shCtlExecute, YES);
  469.             }
  470.         else
  471.             {
  472.             shCtlDefID = shCtlCancel ;
  473.             SendMessage(ahDlg, DM_SETDEFID, ID_PB_CANCEL , 0L);
  474.             EnableWindow(shCtlExecute, NO );
  475.             }
  476.  
  477.         if (awCode == EN_CHANGE)
  478.             {
  479.             //    enable Reset based on the changed New Command Line
  480.             EnableWindow(shCtlReset, YES);
  481.  
  482.             //    adjust the maximum size of the New Command Line
  483.             GetWindowText(shCtlCmd, mpsBuffer, sizeof_mpsBuffer);
  484.             apsCmdLine = strchr(mpsBuffer, ' ');    //  first blank
  485.             if (NULL == apsCmdLine)        //  no blank after app
  486.             apsCmdLine = mpsBuffer + lstrlen(mpsBuffer);
  487.             awCmdLen = apsCmdLine - mpsBuffer + 128;
  488.             if (awCmdLen < lstrlen(mpsBuffer))
  489.             MessageBeep(0);
  490.             SendMessage(shCtlCmd, EM_LIMITTEXT, awCmdLen, 0L);
  491.             }
  492.         break;
  493.  
  494.         case ID_RB_DEF:
  495.         case ID_RB_MIN:
  496.         case ID_RB_MAX:
  497.         //  enable Reset based on clicked radio buttons
  498.         if (awCode == BN_CLICKED
  499.         ||  awCode == BN_DOUBLECLICKED)
  500.             if (awParam != siID_RB_SW)
  501.             EnableWindow(shCtlReset, YES);
  502.         break;
  503.         }
  504.     switch (awParam)
  505.         {
  506.         case ID_PB_RESET:
  507.         //  move the focus to Reset, if it's not there
  508.         SetFocus(shCtlReset);
  509.  
  510.         //  reset the New Command Line edit control
  511.         SendMessage(shCtlCmd, EM_LIMITTEXT, swCmdLen, 0L);
  512.         SetWindowText(shCtlCmd, mpsCmdLine);
  513.         SendMessage(shCtlCmd, EM_SETSEL, 0, MAKELONG(0, 0xFFFF));
  514.         SetFocus(shCtlCmd);
  515.  
  516.         //  reset the radio button controls
  517.         CheckRadioButton(ahDlg, ID_RB_DEF, ID_RB_MAX, siID_RB_SW);
  518.  
  519.         //  reset the button styles
  520.         SendMessage(shCtlDefID, BM_SETSTYLE, BS_DEFPUSHBUTTON, 1L);
  521.         SendMessage(shCtlReset, BM_SETSTYLE, BS_PUSHBUTTON   , 1L);
  522.         //  fall through
  523.         case ID_E_CMD:
  524.         case ID_RB_DEF:
  525.         case ID_RB_MIN:
  526.         case ID_RB_MAX:
  527.         //  disable Reset based on New Command Line and radio buttons
  528.         if (IsDlgButtonChecked(ahDlg, siID_RB_SW))
  529.             {
  530.             GetWindowText(shCtlCmd, mpsBuffer, sizeof_mpsBuffer);
  531.             if (0 == strcmp(mpsBuffer, mpsCmdLine))
  532.             EnableWindow(shCtlReset, NO);
  533.             }
  534.         break;
  535.  
  536.         case ID_PB_EXECUTE:
  537.         //  if "usage" dialog box, done
  538.         if (sbUsage)
  539.             {
  540.             EndDialog(ahDlg, 0);    //  OK
  541.             break;
  542.             }
  543.  
  544.         //  get the changed New Command Line
  545.         GetWindowText(shCtlCmd, mpsCmdLine, sizeof_mpsCmdLine);
  546.  
  547.         //  remove any CR/LFs that were inserted in the edit control
  548.         while ((apsCmdLine = strchr(mpsCmdLine, '\r'))
  549.         ||     (apsCmdLine = strchr(mpsCmdLine, '\n')))
  550.                *apsCmdLine = ' ';
  551.  
  552.         //  possibly change iCmdShow
  553.         if (NO == IsDlgButtonChecked(ahDlg, siID_RB_SW))
  554.             {
  555.             mnpWinMain->iCmdShow = SW_SHOW;
  556.             if (IsDlgButtonChecked(ahDlg, ID_RB_MIN))
  557.             mnpWinMain->iCmdShow = SHOW_MINIMIZED;
  558.             if (IsDlgButtonChecked(ahDlg, ID_RB_MAX))
  559.             mnpWinMain->iCmdShow = SHOW_MAXIMIZED;
  560.             }
  561.         //  fall through
  562.         case ID_PB_CANCEL:
  563.         EndDialog(ahDlg, awParam);    //  Execute, Cancel or OK
  564.         break;
  565.  
  566.         case ID_PB_USAGE:
  567.         //  move the focus to Usage, if it's not there
  568.         SetFocus(shCtlUsage);
  569.         UpdateWindow(ahDlg);
  570.  
  571.         //  put up a "usage" dialog box
  572.         mhDlg = ahDlg;    //  required for Usage recursion
  573.         argc = 1;    //  for recursion
  574.         WinMain(mnpWinMain->hInst,
  575.             mnpWinMain->hPrevInst,
  576.             mnpWinMain->lpsCmdLine,
  577.             mnpWinMain->iCmdShow);
  578.         mhDlg = 0;    //  required for Usage recursion
  579.  
  580.         //  move the focus to the New Command Line edit control
  581.         SetFocus(shCtlCmd);
  582.  
  583.         //  reset the button styles
  584.         SendMessage(shCtlDefID, BM_SETSTYLE, BS_DEFPUSHBUTTON, 1L);
  585.         SendMessage(shCtlUsage, BM_SETSTYLE, BS_PUSHBUTTON   , 1L);
  586.         break;
  587.         }
  588.     return YES;    //  did process the message
  589.     }
  590. return NO;    //  didn't process the message
  591. }
  592.  
  593.